home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 2108 / 2108.xpi / content / edit.js < prev    next >
Text File  |  2009-08-19  |  11KB  |  319 lines

  1. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  2.  
  3. var saved = false;
  4. var style = null;
  5. var strings = null;
  6. var codeE, nameE, tagsE, updateUrlE;
  7. var setCode, getCode;
  8. var triggeringDocument = null;
  9. var installPingURL = null;
  10. //because some editors can have different CRLF settings than what we've saved as, we'll only save if the code in the editor has changed. this will prevent update notifications when there are none
  11. var initialCode;
  12.  
  13. const CSSXULNS = "@namespace url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);";
  14. const CSSHTMLNS = "@namespace url(http://www.w3.org/1999/xhtml);";
  15.  
  16. function init() {
  17.  
  18.     nameE = document.getElementById("name");
  19.     tagsE = document.getElementById("tags");
  20.     updateUrlE = document.getElementById("update-url")
  21.     strings = document.getElementById("strings");
  22.  
  23.     if (typeof DiavoloTokenizer == "undefined") {
  24.         //internal editor
  25.         codeE = document.getElementById("internal-code");
  26.         setCode = function(code) {
  27.             codeE.value = code;
  28.         }
  29.         getCode = function() {
  30.             return codeE.value;
  31.         }
  32.         //wrap?
  33.         var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  34.         prefs = prefs.getBranch("extensions.stylish.");
  35.         var wrapLines = prefs.getBoolPref("wrap_lines");
  36.         refreshWordWrap(wrapLines);
  37.         var wrapLinesE = document.getElementById("wrap-lines");
  38.         wrapLinesE.checked = wrapLines;
  39.         wrapLinesE.style.display = "";
  40.     } else {
  41.         //diavolo
  42.         codeE = document.getElementById("diavolo-code");
  43.         setCode = function(code) {
  44.             codeE.textContent = code;
  45.         }
  46.         getCode = function() {
  47.             return codeE.textContent;
  48.         }
  49.         codeE.init();
  50.         codeE.parentNode.selectedIndex = 1;
  51.         // suck in it's all text changes
  52.         document.getElementById("internal-code").__defineSetter__("value", setCode);
  53.         document.getElementById("internal-code").__defineGetter__("value", getCode);
  54.     }
  55.  
  56.     var service = Components.classes["@userstyles.org/style;1"].getService(Components.interfaces.stylishStyle);
  57.     if (window.arguments) {
  58.         if ("id" in window.arguments[0]) {
  59.             style = service.find(window.arguments[0].id, service.CALCULATE_META | service.REGISTER_STYLE_ON_CHANGE);
  60.         } else if ("style" in window.arguments[0]) {
  61.             style = window.arguments[0].style;
  62.             style.mode = service.CALCULATE_META | service.REGISTER_STYLE_ON_CHANGE;
  63.         }
  64.         triggeringDocument = window.arguments[0].triggeringDocument;
  65.         installPingURL = window.arguments[0].installPingURL;
  66.         document.documentElement.setAttribute("windowtype", window.arguments[0].windowType);
  67.     }
  68.  
  69.     if (style) {
  70.         nameE.value = style.name;
  71.         tagsE.value = style.getMeta("tag", {}).join(" ");
  72.         updateUrlE.value = style.updateUrl;
  73.         setCode(style.code);
  74.         // if the style already has an id, it's been previously saved, so this is an edit
  75.         // if the style has no id but has a url, it's an install
  76.         document.documentElement.getButton("extra1").hidden = style.id || !style.url;
  77.         if (style.id) {
  78.             document.title = strings.getFormattedString("editstyletitle", [style.name]);
  79.         } else {
  80.             document.title = strings.getString("newstyletitle");
  81.         }
  82.     } else {
  83.         style = Components.classes["@userstyles.org/style;1"].createInstance(Components.interfaces.stylishStyle);
  84.         document.documentElement.getButton("extra1").hidden = true;
  85.         document.title = strings.getString("newstyletitle");
  86.     }
  87.  
  88.     // the code returned is different for some reason a little later...
  89.     setTimeout(function(){initialCode = getCode()},100);
  90. }
  91.  
  92. function switchToInstall() {
  93.     Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch).setBoolPref("extensions.stylish.editOnInstall", false);
  94.     style.name = nameE.value;
  95.     if (getCode() != initialCode) {
  96.         style.code = getCode();
  97.     }
  98.     stylishCommon.openInstall({style: style, triggeringDocument: triggeringDocument, installPingURL: installPingURL});
  99.     window.close();
  100. }
  101.  
  102. function save() {
  103.     style.name = nameE.value;
  104.     if (!style.name) {
  105.         alert(strings.getString("missingname"));
  106.         return false;
  107.     }
  108.     var code = getCode();
  109.     if (!code) {
  110.         alert(strings.getString("missingcode"));
  111.         return false;
  112.     }
  113.  
  114.     if (!style.id)
  115.         // new styles start out enabled
  116.         style.enabled = true;
  117.     else if (!style.enabled)
  118.         // turn off preview for previously saved disabled styles to avoid flicker
  119.         style.setPreview(false);
  120.  
  121.     if (code != initialCode) {
  122.         style.code = code;
  123.     }
  124.  
  125.     style.removeAllMeta("tag")
  126.     var tags = tagsE.value.split(/[\s,]+/);
  127.     // tags should be unique and not just whitespace
  128.     var uniqueTags = [];
  129.     tags.filter(function(tag) {
  130.         return !/^\s*$/.test(tag);
  131.     }).forEach(function(tag) {
  132.         if (!uniqueTags.some(function(utag) {
  133.             return utag.toLowerCase() == tag.toLowerCase();
  134.         })) {
  135.             uniqueTags.push(tag);
  136.         }
  137.     });
  138.     style.updateUrl = updateUrlE.value;
  139.     uniqueTags.forEach(function(v) {
  140.         style.addMeta("tag", v);
  141.     });
  142.     style.save();
  143.     saved = true;
  144.     if (triggeringDocument) {
  145.         stylishCommon.dispatchEvent(triggeringDocument, "styleInstalled");
  146.     }
  147.     if (installPingURL) {
  148.         var req = new XMLHttpRequest();
  149.         req.open("GET", installPingURL, true);
  150.         stylishCommon.fixXHR(req);
  151.         req.send(null);
  152.     }
  153.     return true;
  154. }
  155.  
  156. function preview() {
  157.     style.name = nameE.value;
  158.     if (getCode() != initialCode) {
  159.         style.code = getCode();
  160.         // once the user has changed once, they've committed to changing so we'll forget the initial
  161.         initialCode = null;
  162.     }
  163.     checkForErrors();
  164.     style.setPreview(true);
  165. }
  166.  
  167. function cancelDialog() {
  168.     return true;
  169. }
  170.  
  171. //turn off preview!
  172. function dialogClosing() {
  173.     style.setPreview(false);
  174.     if (!saved) {
  175.         style.revert();
  176.     }
  177. }
  178.  
  179.  
  180. function checkForErrors() {
  181.     var service = Components.classes["@userstyles.org/style;1"].getService(Components.interfaces.stylishStyle);
  182.     var errors = document.getElementById("errors");
  183.     errors.style.display = "none";
  184.     while (errors.hasChildNodes()) {
  185.         errors.removeChild(errors.lastChild);
  186.     }
  187.     var errorListener = {
  188.         QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIConsoleListener, Components.interfaces.nsISupports]),
  189.         observe: function(message) {
  190.             errors.style.display = "-moz-box";
  191.             var label = document.createElementNS(stylishCommon.XULNS, "label");
  192.             var error = message.QueryInterface(Components.interfaces.nsIScriptError);
  193.  
  194.             label.appendChild(document.createTextNode(error.lineNumber + ":" + error.columnNumber + " " + error.errorMessage));
  195.             errors.appendChild(label);
  196.         }
  197.     }
  198.     style.checkForErrors(getCode(), errorListener);
  199. }
  200.  
  201. //Insert the snippet at the start of the code textbox or highlight it if it's already in there
  202. function insertCodeAtStart(snippet) {
  203.     var position = getCode().indexOf(snippet);
  204.     if (position == -1) {
  205.         //insert the code
  206.         //put some line breaks in if there's already code there
  207.         if (getCode().length > 0) {
  208.             setCode(snippet + "\n" + getCode());
  209.         } else {
  210.             setCode(snippet + "\n");
  211.         }
  212.     }
  213.     //highlight it
  214.     codeE.setSelectionRange(snippet.length + 1, snippet.length + 1);
  215.     codeE.focus();
  216. }
  217.  
  218. function insertCodeAtCaret(snippet) {
  219.     var selectionEnd = codeE.selectionStart + snippet.length;
  220.     setCode(getCode().substring(0, codeE.selectionStart) + snippet + getCode().substring(codeE.selectionEnd, getCode().length));
  221.     codeE.focus();
  222.     codeE.setSelectionRange(selectionEnd, selectionEnd);
  223. }
  224.  
  225. function changeWordWrap(on) {
  226.     var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
  227.     prefs = prefs.getBranch("extensions.stylish.");
  228.     prefs.setBoolPref("wrap_lines", on);
  229.     refreshWordWrap(on);
  230. }
  231.  
  232. function refreshWordWrap(on) {
  233.     //bug 41464 (wrap doesn't work dynamically) workaround
  234.     codeE.style.display = "none";
  235.     codeE.setAttribute("wrap", on ? "on" : "off");
  236.     setTimeout("codeE.style.display = '';", 10);
  237. }
  238.  
  239. function insertChromePath() {
  240.     var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
  241.     var fileHandler = ios.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler);
  242.     var chromePath = fileHandler.getURLSpecFromFile(Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("UChrm", Components.interfaces.nsIFile));
  243.     insertCodeAtCaret(chromePath);
  244. }
  245.  
  246. function insertDataURI() {
  247.     const ci = Components.interfaces;
  248.     const cc = Components.classes;
  249.     const nsIFilePicker = ci.nsIFilePicker;
  250.     var fp = cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
  251.     fp.init(window, strings.getString("dataURIDialogTitle"), nsIFilePicker.modeOpen);
  252.     if (fp.show() != nsIFilePicker.returnOK) {
  253.         return;
  254.     }
  255.     var file = fp.file;
  256.     var contentType = cc["@mozilla.org/mime;1"].getService(ci.nsIMIMEService).getTypeFromFile(file);
  257.     var inputStream = cc["@mozilla.org/network/file-input-stream;1"].createInstance(ci.nsIFileInputStream);
  258.     inputStream.init(file, 0x01, 0600, 0);
  259.     var stream = cc["@mozilla.org/binaryinputstream;1"].createInstance(ci.nsIBinaryInputStream);
  260.     stream.setInputStream(inputStream);
  261.     var encoded = btoa(stream.readBytes(stream.available()));
  262.     stream.close();
  263.     inputStream.close();
  264.     insertCodeAtCaret("data:" + contentType + ";base64," + encoded);
  265. }
  266.  
  267. var finder = {
  268.     QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsITypeAheadFind, Components.interfaces.nsISupports]),
  269.     nsITAF: Components.interfaces.nsITypeAheadFind,
  270.  
  271.     init: function(docshell) {},
  272.  
  273.     find: function(s, linksOnly) {
  274.         this.searchString = s;
  275.         return this.findFromIndex(0, false);
  276.     },
  277.  
  278.     findAgain: function(backwards, linksOnly) {
  279.         return this.findFromIndex(codeE.selectionStart + (backwards ? 0 : 1), backwards);
  280.     },
  281.  
  282.     findFromIndex: function(index, backwards) {
  283.         var start = backwards ? codeE.value.substring(0, index).lastIndexOf(this.searchString) : codeE.value.indexOf(this.searchString, index);
  284.         var result;
  285.         if (start >= 0) {
  286.             result = this.nsITAF.FIND_FOUND;
  287.         } else if (index == 0) {
  288.             result = this.nsITAF.FIND_NOTFOUND;
  289.         } else {
  290.             // try again, start from the start
  291.             start = backwards ? codeE.value.lastIndexOf(this.searchString) : codeE.value.indexOf(this.searchString);
  292.             result = start == -1 ? this.nsITAF.FIND_NOTFOUND : this.nsITAF.FIND_WRAPPED;
  293.         }
  294.         codeE.editor.selection.removeAllRanges();
  295.         if (start >= 0) {
  296.             codeE.setSelectionRange(start, start + this.searchString.length);
  297.             codeE.editor.selectionController.setDisplaySelection(2);
  298.             codeE.editor.selectionController.scrollSelectionIntoView(1, 0, false);
  299.         } else
  300.             codeE.setSelectionRange(0, 0);
  301.         return result;
  302.     },
  303.  
  304.     setDocShell: function(docshell) {},
  305.     setSelectionModeAndRepaint: function(toggle) {},
  306.     collapseSelection: function(toggle) {},
  307.  
  308.     searchString: null,
  309.     caseSensitive: false,
  310.     foundLink: null,
  311.     foundEditable: null,
  312.     currentWindow: null
  313. }
  314. window.addEventListener("load", function() {
  315.     var findBar = document.getElementById("findbar");
  316.     document.getElementById("internal-code").fastFind = finder;
  317.     findBar.open();
  318. }, false);
  319.